package cn.hinglo.common.config.proxy;

import cn.hinglo.common.annotation.Value;
import cn.hinglo.common.util.PropertiesKit;
import cn.hutool.core.util.StrUtil;
import com.jfinal.proxy.ProxyFactory;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;

/**
 * @createTime: 2019/12/16 : 15:48
 * @author: HingLo
 * @description: 自定义的代理对象。方便用于自动注入一些值
 */
@Slf4j
public class SelfProxyFactory extends ProxyFactory {
    /***
     * 表单时前缀
     */
    private final static String PREFIX = "#{";
    /***
     * 表达式后缀
     */
    private final static String SUFFIX = "}";


    @Override
    public <T> T get(Class<T> target) {
        try {
            Class<T> ret = (Class<T>) cache.get(target);
            T result = null;
            if (ret != null) {
                result = (T) ret.newInstance();
            } else {
                result = getProxyClass(target).newInstance();
            }
            Class<?> resultClass = result.getClass();


            Field[] fields = resultClass.getDeclaredFields();
            for (Field field : fields) {
                Value annotation = field.getAnnotation(Value.class);
                if (annotation != null) {
                    // 表达式
                    String expr = annotation.value();
                    if (StrUtil.startWith(expr, PREFIX) && StrUtil.endWith(expr, SUFFIX)) {
                        // application.properties 中的key
                        String key = StrUtil.removeSuffix(StrUtil.removePrefix(expr, PREFIX), SUFFIX);
                        String keyValue = PropertiesKit.get(key, null);
                        field.setAccessible(true);
                        if (field.getType() == Byte.class) {
                            field.set(result, Byte.valueOf(keyValue));
                        } else if (field.getType() == Short.class) {
                            field.set(result, Short.valueOf(keyValue));
                        } else if (field.getType() == Integer.class) {
                            field.set(result, Integer.valueOf(keyValue));
                        } else if (field.getType() == Long.class) {
                            field.set(result, Long.valueOf(keyValue));
                        } else if (field.getType() == Double.class) {
                            field.set(result, Double.valueOf(keyValue));
                        } else if (field.getType() == Float.class) {
                            field.set(result, Float.valueOf(keyValue));
                        } else if (field.getType() == String.class) {
                            field.set(result, keyValue);
                        }
                    }
                }

            }
            return result;
        } catch (ReflectiveOperationException e) {
            throw new RuntimeException(e);
        }
    }
}
